/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.jprvyd.gui.list;

import cz.muni.fi.pb138.jprvyd.*;
import cz.muni.fi.pb138.jprvyd.gui.form.PaymentForm;
import cz.muni.fi.pb138.jprvyd.gui.model.Payment_TableModel;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;

/**
 *
 * @author Jan
 */
public class PaymentsList extends javax.swing.JFrame {


    private PaymentManager paymentManager;
    private SwingWorker swingWorker;
    List<Payment> payments;
    int rowIndex;
    public final int REMOVE = 0;
    public final int ADD = 1;
    public final int EDIT = 2;
    
    private final int NONE = 0;   
    private final int VAR_SYMBOL = 1;
    private final int DATE = 2;  
    private final int BANK_ACCOUNT = 3;


    /**
     * Creates new form InvoiceForm
     */
    public PaymentsList() {

        paymentManager = new PaymentManagerImpl();
        payments = paymentManager.getAllPayments();
        rowIndex = -1;
        initComponents();
    }

    private class editSwingWorker extends SwingWorker<Integer, Void> {

        PaymentsList frame;
        Integer paymentVariableSymbol;
        PaymentManager paymentManager;
        
        public editSwingWorker(PaymentsList frame, Integer paymentVariableSymbol, PaymentManager paymentManager) {
            
            this.frame = frame;
            this.paymentVariableSymbol = paymentVariableSymbol;
            this.paymentManager = paymentManager;
        }                

        @Override
        protected Integer doInBackground() throws Exception {            
            Payment payment = paymentManager.getPaymentByVariableSymbol(paymentVariableSymbol);
            PaymentForm paymentForm = new PaymentForm(frame, payment);
            paymentForm.setVisible(true);
            return 0;
        }

        @Override
        protected void done() {
            swingWorker = null;
        }
    }

    private class deleteSwingWorker extends SwingWorker<Integer, Void> {

        PaymentManager paymentManager;
        
        public deleteSwingWorker(PaymentManager paymentManager) {
            this.paymentManager = paymentManager;
        }
        
        

        @Override
        protected Integer doInBackground() throws Exception {
            rowIndex = tablePayments.getSelectedRow();
            Payment_TableModel model = (Payment_TableModel) tablePayments.getModel();
            Integer paymentVariableSymbol = (Integer) model.getValueAt(rowIndex, 0);
            Payment payment = paymentManager.getPaymentByVariableSymbol(paymentVariableSymbol);
            paymentManager.removePayment(payment.getId());

            refreshPayments(payments.get(rowIndex), REMOVE);
            return 0;
        }

        @Override
        protected void done() {
            swingWorker = null;
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        tablePayments = new javax.swing.JTable();
        buttonNewPayment = new javax.swing.JButton();
        buttonDeletePayment = new javax.swing.JButton();
        buttonEditPayment = new javax.swing.JButton();
        labelFilter = new javax.swing.JLabel();
        comboBoxFilter = new javax.swing.JComboBox();
        textFieldFilter = new javax.swing.JTextField();
        buttonFilter = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("JPrVyd - Payments manager");

        tablePayments.setModel(new Payment_TableModel(payments));
        tablePayments.getTableHeader().setReorderingAllowed(false);
        tablePayments.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tablePaymentsMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(tablePayments);

        buttonNewPayment.setText("New payment");
        buttonNewPayment.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonNewPaymentActionPerformed(evt);
            }
        });

        buttonDeletePayment.setText("Delete payment");
        buttonDeletePayment.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDeletePaymentActionPerformed(evt);
            }
        });

        buttonEditPayment.setText("Edit payment");
        buttonEditPayment.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonEditPaymentActionPerformed(evt);
            }
        });

        labelFilter.setText("Filter:");

        comboBoxFilter.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "None", "Variable symbol", "Date", "Bank account"}));
        comboBoxFilter.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                comboBoxFilterActionPerformed(evt);
            }
        });

        textFieldFilter.setEnabled(false);
        textFieldFilter.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                textFieldFilterMouseClicked(evt);
            }
        });

        buttonFilter.setText("Filter");
        buttonFilter.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonFilterActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(buttonNewPayment)
                                .addGap(18, 18, 18)
                                .addComponent(buttonEditPayment)
                                .addGap(133, 133, 133)
                                .addComponent(buttonDeletePayment)))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(labelFilter)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(comboBoxFilter, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(textFieldFilter, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonFilter)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(labelFilter)
                    .addComponent(comboBoxFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(textFieldFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(buttonFilter))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 17, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(buttonNewPayment)
                    .addComponent(buttonDeletePayment)
                    .addComponent(buttonEditPayment))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void buttonNewPaymentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonNewPaymentActionPerformed
        PaymentForm paymentForm = new PaymentForm(this);
        paymentForm.setVisible(true);
    }//GEN-LAST:event_buttonNewPaymentActionPerformed

    private void buttonEditPaymentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEditPaymentActionPerformed
        rowIndex = tablePayments.getSelectedRow();
        if (rowIndex == -1) {
            JOptionPane.showMessageDialog(rootPane, "No invoice selected");
        } else {
            if (swingWorker != null) {
                throw new IllegalStateException("Operation in progress");
            }
            rowIndex = tablePayments.getSelectedRow();
            Payment_TableModel model = (Payment_TableModel) tablePayments.getModel();
            Integer paymentVariableSymbol = (Integer) model.getValueAt(rowIndex, 0);
            swingWorker = new editSwingWorker(this, paymentVariableSymbol, paymentManager);
            swingWorker.execute();
            tablePayments.updateUI();
        }
    }//GEN-LAST:event_buttonEditPaymentActionPerformed

    private void buttonDeletePaymentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDeletePaymentActionPerformed
        rowIndex = tablePayments.getSelectedRow();
        if (rowIndex == -1) {
            JOptionPane.showMessageDialog(rootPane, "No invoice selected");
        } else {
            int choice = JOptionPane.showConfirmDialog(rootPane, "Delete invoice?", null, JOptionPane.YES_NO_OPTION);
            if (choice == 0) {
                if (swingWorker != null) {
                    throw new IllegalStateException("Operation in progress");
                }
                swingWorker = new deleteSwingWorker(paymentManager);
                swingWorker.execute();
                tablePayments.updateUI();

            }
        }
    }//GEN-LAST:event_buttonDeletePaymentActionPerformed

    private void tablePaymentsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tablePaymentsMouseClicked
        if (rowIndex == tablePayments.getSelectedRow()) {
            this.buttonEditPaymentActionPerformed(null);
        } else {
            rowIndex = tablePayments.getSelectedRow();
        }
    }//GEN-LAST:event_tablePaymentsMouseClicked

    private void comboBoxFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboBoxFilterActionPerformed
        int index = comboBoxFilter.getSelectedIndex();
        switch (index) {
            case NONE:
                textFieldFilter.setText("");
                textFieldFilter.setEnabled(false);
                break;            
            case VAR_SYMBOL:
                textFieldFilter.setText("Enter variable symbol");
                textFieldFilter.setEnabled(true);
                break;
            case DATE:
                textFieldFilter.setText("DD. MM. YYYY");
                textFieldFilter.setEnabled(true);
                break;
            case BANK_ACCOUNT:
                textFieldFilter.setText("Enter bank account");
                textFieldFilter.setEnabled(true);
                break;
        }
    }//GEN-LAST:event_comboBoxFilterActionPerformed

    private void textFieldFilterMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_textFieldFilterMouseClicked
        
    }//GEN-LAST:event_textFieldFilterMouseClicked

    private void buttonFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonFilterActionPerformed
        buttonFilter.setEnabled(false);
        int index = comboBoxFilter.getSelectedIndex();
        String content = textFieldFilter.getText();
        DateFormat dateParser = new SimpleDateFormat("dd. MM. yyyy");
        Payment payment = null;
        List<Payment> paymentsFiltered = null;
        boolean onePayment = false;
        switch (index) {
            case NONE:
                try {
                    paymentsFiltered = paymentManager.getAllPayments();
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(rootPane, "Error while fetching payments");
                }
                break;            
            case VAR_SYMBOL:
                int varSymbol = 0;
                try {
                    varSymbol = Integer.parseInt(content);
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(rootPane, "Enter correct variable symbol");
                }
                if (varSymbol != 0) {
                    try {
                        payment = paymentManager.getPaymentByVariableSymbol(varSymbol);
                        onePayment = true;
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(rootPane, "Error while fetching payments");
                    }
                }
                break;
            case DATE:
                Date date = null;
                try {
                    date = dateParser.parse(content);
                } catch (ParseException ex) {
                    JOptionPane.showMessageDialog(rootPane, "Enter a correct date (DD. MM. YYYY)");
                }
                if (date != null) {
                    try {
                        paymentsFiltered = paymentManager.getPaymentsByDate(date);
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(rootPane, "Error while fetching payments");
                    }
                }
                break;
             case BANK_ACCOUNT:
                if (content != null) {
                    try {
                        paymentsFiltered = paymentManager.getPaymentsByBankAccount(content);
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(rootPane, "Error while fetching payments");
                    }
                }                
                break;   
             
            
        }
        
        if (payment != null) {
            PaymentForm form = new PaymentForm(this, payment);
            form.setVisible(true);
        } else if (paymentsFiltered != null) {
            payments = paymentsFiltered;
            tablePayments.setModel(new Payment_TableModel(payments));
        } else if (onePayment) {
            JOptionPane.showMessageDialog(rootPane, "No payment found");
        }
        buttonFilter.setEnabled(true);
    }//GEN-LAST:event_buttonFilterActionPerformed

    public void refreshPayments(Payment payment, int operation) {
        if (operation == REMOVE) {
            payments.remove(payment);
        } else if (operation == ADD) {
            payments.add(payment);
        } else if (operation == EDIT) {
            payments.set(rowIndex, payment);
        }
        tablePayments.updateUI();
        rowIndex = -1;
    }
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(PaymentsList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(PaymentsList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(PaymentsList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(PaymentsList.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new PaymentsList().setVisible(true);
            }
        });


    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonDeletePayment;
    private javax.swing.JButton buttonEditPayment;
    private javax.swing.JButton buttonFilter;
    private javax.swing.JButton buttonNewPayment;
    private javax.swing.JComboBox comboBoxFilter;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel labelFilter;
    public javax.swing.JTable tablePayments;
    private javax.swing.JTextField textFieldFilter;
    // End of variables declaration//GEN-END:variables
}
